using System;
using System.CodeDom;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Runtime.Serialization;
namespace Net35.Xrm.Sdk
{
	internal sealed class ProxySerializationSurrogate : IDataContractSurrogate
	{
		private Assembly _proxyTypesAssembly;
		internal ProxySerializationSurrogate(Assembly proxyTypesAssembly)
		{
			this._proxyTypesAssembly = proxyTypesAssembly;
		}
		object IDataContractSurrogate.GetCustomDataToExport(Type clrType, Type dataContractType)
		{
			return null;
		}
		object IDataContractSurrogate.GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
		{
			return null;
		}
		Type IDataContractSurrogate.GetDataContractType(Type type)
		{
			if (type.IsAssignableFrom(typeof(OrganizationRequest)))
			{
				return typeof(OrganizationRequest);
			}
			if (type.IsAssignableFrom(typeof(OrganizationResponse)))
			{
				return typeof(OrganizationResponse);
			}
			if (type.IsAssignableFrom(typeof(Entity)))
			{
				return typeof(Entity);
			}
			return type;
		}
		object IDataContractSurrogate.GetDeserializedObject(object obj, Type targetType)
		{
			bool supportIndividualAssemblies = this._proxyTypesAssembly != null;
			OrganizationResponse organizationResponse = obj as OrganizationResponse;
			if (organizationResponse != null)
			{
				Type typeForName = KnownProxyTypesProvider.GetInstance(supportIndividualAssemblies).GetTypeForName(organizationResponse.ResponseName, this._proxyTypesAssembly);
				if (typeForName == null)
				{
					return obj;
				}
				OrganizationResponse organizationResponse2 = (OrganizationResponse)Activator.CreateInstance(typeForName);
				organizationResponse2.ResponseName = organizationResponse.ResponseName;
				organizationResponse2.Results = organizationResponse.Results;
				return organizationResponse2;
			}
			else
			{
				Entity entity = obj as Entity;
				if (entity == null)
				{
					return obj;
				}
				Type typeForName2 = KnownProxyTypesProvider.GetInstance(supportIndividualAssemblies).GetTypeForName(entity.LogicalName, this._proxyTypesAssembly);
				if (typeForName2 == null)
				{
					return obj;
				}
				Entity entity2 = (Entity)Activator.CreateInstance(typeForName2);
				entity.ShallowCopyTo(entity2);
				return entity2;
			}
		}
		void IDataContractSurrogate.GetKnownCustomDataTypes(Collection<Type> customDataTypes)
		{
		}
		object IDataContractSurrogate.GetObjectToSerialize(object obj, Type targetType)
		{
			if (obj.GetType().IsSubclassOf(typeof(OrganizationRequest)))
			{
				OrganizationRequest organizationRequest = (OrganizationRequest)obj;
				bool supportIndividualAssemblies = this._proxyTypesAssembly != null;
				Type typeForName = KnownProxyTypesProvider.GetInstance(supportIndividualAssemblies).GetTypeForName(organizationRequest.RequestName, this._proxyTypesAssembly);
				if (typeForName == null)
				{
					return obj;
				}
				return new OrganizationRequest
				{
					RequestName = organizationRequest.RequestName,
					Parameters = organizationRequest.Parameters,
					RequestId = organizationRequest.RequestId
				};
			}
			else
			{
				if (obj.GetType().IsSubclassOf(typeof(Entity)))
				{
					Entity entity = (Entity)obj;
					Entity entity2 = new Entity();
					entity.ShallowCopyTo(entity2);
					return entity2;
				}
				return obj;
			}
		}
		Type IDataContractSurrogate.GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
		{
			return null;
		}
		System.CodeDom.CodeTypeDeclaration IDataContractSurrogate.ProcessImportedType(System.CodeDom.CodeTypeDeclaration typeDeclaration, System.CodeDom.CodeCompileUnit compileUnit)
		{
			return null;
		}
	}
}
